package org.dolphin.dao.impl;

import java.math.BigDecimal;
import java.util.List;
import org.dolphin.base.constant.Measurement;
import org.dolphin.dao.UomDao;
import org.dolphin.dao.util.SessionHelper;
import org.dolphin.entity.measurement.MeasurementConversion;
import org.dolphin.entity.measurement.UnitOfMeasurement;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository(value = "uomDao")
public class UomDaoImpl implements UomDao {
  @Autowired(required = true)
  private SessionFactory sessionFactory;

  protected DetachedCriteria buildUomConversionCriteria() {
    DetachedCriteria dc = DetachedCriteria.forClass(MeasurementConversion.class);
    return dc;
  }

  protected DetachedCriteria buildUomCriteria() {
    DetachedCriteria dc = DetachedCriteria.forClass(UnitOfMeasurement.class);
    return dc;
  }

  @Override
  public UnitOfMeasurement getUnitOfMeasurement(Measurement measurement) {
    DetachedCriteria dc = buildUomCriteria();
    dc.add(Restrictions.eq("measurement", measurement));
    Session session = SessionHelper.getCurrentSession(sessionFactory);
    Criteria criteria = dc.getExecutableCriteria(session);
    UnitOfMeasurement unitOfMeasurement = (UnitOfMeasurement) criteria.uniqueResult();
    return unitOfMeasurement;
  }

  @SuppressWarnings("unchecked")
  @Override
  public BigDecimal getUomConversion(Measurement source, Measurement target) {
    DetachedCriteria dc = buildUomConversionCriteria();
    dc.createCriteria("pk.source", "s");
    dc.createCriteria("pk.target", "t");
    dc.add(Restrictions.eq("s.measurement", source));
    dc.add(Restrictions.eq("t.measurement", target));
    Session session = SessionHelper.getCurrentSession(sessionFactory);
    Criteria criteria = dc.getExecutableCriteria(session);
    List<MeasurementConversion> list = criteria.list();
    if (list != null && !list.isEmpty()) {
      MeasurementConversion conversion = list.get(0);
      return conversion.getValue();
    }
    return null;
  }
}
